#include "config.h"
#include "ot-fs-utils.h"
+#include "libgsystem.h"
+#include <attr/xattr.h>
int
ot_opendirat (int dfd, const char *path, gboolean follow)
return TRUE;
}
+GBytes *
+ot_lgetxattrat (int dfd,
+ const char *path,
+ const char *attribute,
+ GError **error)
+{
+ /* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer:
+ * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
+ */
+ gs_free char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
+ GBytes *bytes = NULL;
+ ssize_t bytes_read, real_size;
+ char *buf;
+
+ do
+ bytes_read = lgetxattr (full_path, attribute, NULL, 0);
+ while (G_UNLIKELY (bytes_read < 0 && errno == EINTR));
+ if (G_UNLIKELY (bytes_read < 0))
+ {
+ ot_util_set_error_from_errno (error, errno);
+ goto out;
+ }
+
+ buf = g_malloc (bytes_read);
+ do
+ real_size = lgetxattr (full_path, attribute, buf, bytes_read);
+ while (G_UNLIKELY (real_size < 0 && errno == EINTR));
+ if (G_UNLIKELY (real_size < 0))
+ {
+ ot_util_set_error_from_errno (error, errno);
+ g_free (buf);
+ goto out;
+ }
+
+ bytes = g_bytes_new_take (buf, real_size);
+ out:
+ return bytes;
+}
+
+gboolean
+ot_lsetxattrat (int dfd,
+ const char *path,
+ const char *attribute,
+ const void *value,
+ gsize value_size,
+ int flags,
+ GError **error)
+{
+ /* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer:
+ * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
+ */
+ gs_free char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
+ int res;
+
+ do
+ res = lsetxattr (full_path, "user.ostreemeta", value, value_size, flags);
+ while (G_UNLIKELY (res == -1 && errno == EINTR));
+ if (G_UNLIKELY (res == -1))
+ {
+ ot_util_set_error_from_errno (error, errno);
+ return FALSE;
+ }
+
+ return TRUE;
+}